package com.dwk.qa.utils.jmeter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.save.CSVSaveService;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.visualizers.SamplingStatCalculator;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Priority;

import kg.apc.emulators.TestJMeterUtils;

/**
 * 给定一个jtl文件 生成聚合报告数据
 * 
 * @author 董文科
 *
 */
public class MyAverageReportGenerator {

	static {
		LoggingManager.setPriority(Priority.NONE);
		TestJMeterUtils.createJmeterEnv();
	}

	/**
	 * 
	 * @param filename jtl文件的路径
	 * @return 计算后的聚合报告
	 * @throws Exception
	 */
	public static String calculator(File file) throws Exception {
		String[] split = file.getName().split("-");
		SamplingStatCalculator ss = new SamplingStatCalculator(split[0]);

		processSamples(file.getAbsolutePath(), new ResultCollector(), ss);

//		System.out.println(
//				"Label\t# Samples\tAverage\tMedian\t90% Line\t95% Line\t99% Line\tMin\tMax\tError %\tThroughput\tReceived KB/sec\tSent KB/sec");
		return ss.getLabel() + "\t" 
				+ split[2] + "\t" 	
				+ split[4] + "\t" 	
				+ ss.getCount() + "\t" 	
				+ ss.getMean() + "\t" + ss.getMedian() + "\t"
				+ ss.getPercentPoint(0.9) + "\t" + ss.getPercentPoint(0.95) + "\t" + ss.getPercentPoint(0.99) + "\t"
				+ ss.getMin() + "\t" + ss.getMax() + "\t" + ss.getErrorPercentage() + "\t" + ss.getMaxThroughput()
				+ "\t" + ss.getKBPerSecond() + "\t" + ss.getSentKBPerSecond();
	}

	/**
	 * Read Samples from a file; handles quoted strings.
	 * 
	 * @param filename
	 *            input file
	 * @param resultCollector
	 *            the parent collector
	 * @param ss
	 * @return
	 * @throws IOException
	 *             when the file referenced by <code>filename</code> can't be
	 *             read correctly
	 * @throws Exception
	 */
	public static void processSamples(String filename, ResultCollector resultCollector,
			SamplingStatCalculator ss) throws Exception {
		BufferedReader dataReader = null;
		final boolean errorsOnly = resultCollector.isErrorLogging();
		final boolean successOnly = resultCollector.isSuccessOnlyLogging();
		try {
			dataReader = new BufferedReader(new InputStreamReader(new FileInputStream(filename),
					SaveService.getFileEncoding(StandardCharsets.UTF_8.name())));
			dataReader.mark(400);// Enough to read the header column names
			// Get the first line, and see if it is the header
			String line = dataReader.readLine();
			if (line == null) {
				throw new IOException(filename + ": unable to read header line");
			}
			long lineNumber = 1;
			SampleSaveConfiguration saveConfig = CSVSaveService.getSampleSaveConfiguration(line, filename);
			if (saveConfig == null) {// not a valid header
				// log.info(filename + " does not appear to have a valid header.
				// Using default configuration.");
				saveConfig = (SampleSaveConfiguration) resultCollector.getSaveConfig().clone(); // may
																								// change
																								// the
																								// format
																								// later
				dataReader.reset(); // restart from beginning
				lineNumber = 0;
			}
			String[] parts;
			final char delim = saveConfig.getDelimiter().charAt(0);
			// TODO: does it matter that an empty line will terminate the loop?
			// CSV output files should never contain empty lines, so probably
			// not
			// If so, then need to check whether the reader is at EOF
			while ((parts = CSVSaveService.csvReadFile(dataReader, delim)).length != 0) {
				lineNumber++;

				// Method makeResultFromDelimitedString =
				// initialClass.getMethod("makeResultFromDelimitedString",
				// new Class[] { new String[0].getClass() });// $NON-NLS-1$
				// makeResultFromDelimitedString.invoke(instance, new Object[] {
				// args });

				Method method = CSVSaveService.class.getDeclaredMethod("makeResultFromDelimitedString",
						new Class[] { new String[0].getClass(), SampleSaveConfiguration.class, long.class });
				method.setAccessible(true);

				SampleEvent event = (SampleEvent) method.invoke(null, parts, saveConfig, lineNumber);

				// SampleEvent event =
				// CSVSaveService.makeResultFromDelimitedString(parts,
				// saveConfig, lineNumber);
				if (event != null) {
					final SampleResult result = event.getResult();
					if (ResultCollector.isSampleWanted(result.isSuccessful(), errorsOnly, successOnly)) {
						// visualizer.add(result);
						ss.addSample(result);
					}
				}
			}
		} finally {
			JOrphanUtils.closeQuietly(dataReader);
		}
//		return ss;
	}
}
